import datetime

from core import config

from pydantic import BaseModel, Field
from typing import List, Optional, Any

from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine, Column, Integer, String, Boolean, JSON, TEXT, DateTime

# 连接数据库
engine = create_engine(config.DATABASE_URL)
Base = declarative_base()


class CustomDict:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

    def __getattr__(self, name):
        # 当属性不存在时，返回 None
        return None

    def __getitem__(self, key):
        # 使用 getattr 来获取属性，如果不存在则返回 None
        return getattr(self, key, None)


# 数据库表的定义
class ProcessResultDB(Base):
    __tablename__ = 'process_results'  # 表名

    # 定义字段
    id = Column(Integer, primary_key=True, autoincrement=True)  # 主键
    mark_id = Column(String(40), default='')
    valid = Column(Boolean, default=False)  # 是否合格
    reason = Column(JSON, default="")  # 原因
    url = Column(TEXT, default="")  # 当前资源地址
    depth = Column(Integer, default=0)  # 目前解析深度
    forward_urls = Column(JSON, default=[])  # 先前经历的页面（数组）
    note = Column(TEXT, default="")  # 标记
    fix_info = Column(String(40), default='')  # 修复标记
    create_time = Column(DateTime, default=datetime.datetime.now)

    def __format__(self, format_spec):
        return (f"<ProcessResult\n"
                f"    valid        = {self.valid}\n"
                f"    reason       = {self.reason}\n"
                f"    url          = {self.url}\n"
                f"    depth        = {self.depth}\n"
                f"    forward_urls = {self.forward_urls}\n"
                f"    note         = {self.note}\n"
                f">")

    def __str__(self):
        return self.__format__('')


class ProcessResult(BaseModel):
    """处理完毕结果类（Pydantic 模型）"""

    mark_id: str = Field(
        default='',
        description="任务的标记ID"
    )
    valid: bool = Field(
        default=False,
        description="是否合格。True 表示合格，False 表示不合格。"
    )
    reason: Any = Field(
        default=None,
        description="原因说明，用于描述处理结果的详细信息。"
    )
    url: str = Field(
        default="",
        description="当前资源地址，表示当前处理的页面或资源的 URL。"
    )
    depth: int = Field(
        default=0,
        description="当前解析深度，表示从起始页面到当前页面的跳转次数。"
    )
    forward_urls: List[str] = Field(
        default_factory=list,
        description="先前经历的页面 URL 列表，表示从起始页面到当前页面的路径。"
    )
    note: str = Field(
        default="",
        description="处理结果的描述"
    )

    def __format__(self, format_spec):
        return (f"<ProcessResult\n"
                f"    valid        = {self.valid}\n"
                f"    reason       = {self.reason}\n"
                f"    url          = {self.url}\n"
                f"    depth        = {self.depth}\n"
                f"    forward_urls = {self.forward_urls}\n"
                f"    note         = {self.note}\n"
                f">")

    def __str__(self):
        return self.__format__('')

    def to_sqlalchemy(self) -> ProcessResultDB:
        return ProcessResultDB(
            mark_id=self.mark_id,
            valid=self.valid,
            reason=self.reason,
            url=self.url,
            depth=self.depth,
            forward_urls=self.forward_urls,
            note=self.note
        )


# 数据库表创建
Base.metadata.create_all(engine, checkfirst=True)


def db_session():
    Session = sessionmaker(bind=engine)
    return Session()
